/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import javax.sip.InvalidArgumentException;
import javax.sip.header.TimeStampHeader;

/**
 * The Timestamp header field describes when the UAC sent the request to the
 * UAS. When a 100 (Trying) response is generated, any Timestamp header field
 * present in the request MUST be copied into this 100 (Trying) response. If
 * there is a delay in generating the response, the UAS SHOULD add a delay
 * value into the Timestamp value in the response. This value MUST contain the
 * difference between the time of sending of the response and receipt of the
 * request, measured in seconds. Although there is no normative behavior
 * defined here that makes use of the header, it allows for extensions or
 * SIP applications to obtain RTT estimates, that may be used to adjust the
 * timeout value for retransmissions.
 * <p/>
 * For Example:<br>
 * <code>Timestamp: 54</code>
 *
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public class TimeStampHeaderImpl extends HeaderBase implements TimeStampHeader {
    private final static TimeStampHeaderParser parser = new TimeStampHeaderParser();

    private Long time;
    private Integer delay;

    public TimeStampHeaderImpl() {
        super(TimeStampHeader.NAME);
    }

    TimeStampHeaderImpl(byte[] data, int start, int end) {
        super(TimeStampHeader.NAME, data, start, end);
    }

    public Object clone() {
        final TimeStampHeaderImpl header = new TimeStampHeaderImpl();
        header.cloneBase(this);
        if (parsed) {
            header.time = this.time;
            header.delay = this.delay;
        }
        return header;
    }

    protected HeaderParser getParser() {
        return parser;
    }

    protected String getValueAsString() {
        final StringBuilder sb = new StringBuilder();
        if (time != null)
            sb.append(time);
        if (delay != null)
            sb.append(' ').append(delay);
        return sb.toString();
    }

    /**
     * Sets the timestamp value of this TimeStampHeader to the new timestamp
     * value passed to this method.
     *
     * @param timeStamp the new float timestamp value
     * @throws javax.sip.InvalidArgumentException
     *          if the timestamp value argument is a
     *          negative value.
     * @deprecated This method is replaced with {@link #setTime(long)}.
     */
    public void setTimeStamp(float timeStamp) throws InvalidArgumentException {
        parse();
        this.time = (long) timeStamp;
        invalidateHeaderData();
    }

    /**
     * Gets the timestamp value of this TimeStampHeader.
     *
     * @return the timestamp value of this TimeStampHeader
     * @deprecated This method is replaced with {@link #getTime()}.
     */
    public float getTimeStamp() {
        parse();
        return time;
    }

    /**
     * Gets the timestamp value of this TimeStampHeader.
     *
     * @return the timestamp value of this TimeStampHeader
     */
    public long getTime() {
        parse();
        return time;
    }

    /**
     * Sets the timestamp value of this TimeStampHeader to the new timestamp
     * value passed to this method. This method allows applications to conveniantly
     * use System.currentTimeMillis to set the timeStamp value.
     *
     * @param timeStamp the new long timestamp value
     * @throws javax.sip.InvalidArgumentException
     *          if the timestamp value argument is a
     *          negative value.
     */
    public void setTime(long timeStamp) throws InvalidArgumentException {
        parse();
        this.time = timeStamp;
        invalidateHeaderData();
    }

    /**
     * Gets delay of TimeStampHeader. This method returns <code>-1</code> if the
     * delay parameter is not set.
     *
     * @return the delay value of this TimeStampHeader
     * @deprecated This method is replaced with {@link #getTimeDelay()}.
     */

    public float getDelay() {
        parse();
        if (delay == null)
            return -1;
        else
            return delay;
    }

    /**
     * Sets the new delay value of the TimestampHeader to the delay parameter
     * passed to this method
     *
     * @param delay the new float delay value
     * @throws javax.sip.InvalidArgumentException
     *          if the delay value argumenmt is a
     *          negative value other than the default value <code>-1</code>.
     * @deprecated This method is replaced with {@link #setTimeDelay(int)}.
     */

    public void setDelay(float delay) throws InvalidArgumentException {
        parse();
        if (delay == -1)
            this.delay = null;
        else if (delay < 0)
            throw new InvalidArgumentException("The delay cannot be negative!");
        else
            this.delay = (int) delay;
        invalidateHeaderData();
    }

    /**
     * Gets delay of TimeStampHeader. This method returns <code>-1</code> if the
     * delay parameter is not set.
     *
     * @return the delay value of this TimeStampHeader as an integer.
     */

    public int getTimeDelay() {
        parse();
        if (this.delay==null)
            return -1;
        else
            return this.delay;
    }

    /**
     * Sets the new delay value of the TimestampHeader to the delay parameter
     * passed to this method
     *
     * @param delay the new int delay value
     * @throws javax.sip.InvalidArgumentException
     *          if the delay value argumenmt is a
     *          negative value other than the default value <code>-1</code>.
     */

    public void setTimeDelay(int delay) throws InvalidArgumentException {
        parse();
        this.delay = delay;
        invalidateHeaderData();
    }
}
/*
 * $Log$
 */